import { PanelModel } from '../../Basic/UI/PanelModel';
import { MathUtil } from '../../Util/MathUtil';
import { CellMachine } from './CellMachine';
import { GameColor } from '../Model/GameColor';
import { OrderMachine } from './OrderMachine';
import { PropMachine } from './PropMachine';
import { DataMgr, GameData } from '../../Basic/Manager/DataManager';
import { GameParams } from '../../Basic/Config/DataConfig';
import { TB } from '../../Data/Types';
import { SettlementModel } from '../Settlement/SettlementModel';
import { Tool } from '../../Util/Tool';
import { RankModel } from '../Dialog/RankModel';
import { AudioManager } from '../../Basic/Manager/AudioManager';
import { SoundCode } from '../../Basic/Config/BaseEnum';
import { Node, Size, Sprite, tween, Tween, UITransform, v3, Vec3 } from 'cc';
import { GEEvent, GravityModel } from '../../Basic/Model/SDK/GravityModel';

export type SingleOrder = {
  cake: string;
  count: number;
};

export class GameModel extends PanelModel {
  className: string = 'GameModel';
  loadRes: string = 'maingame/game/GamePanel';
  basePanel = null;
  cellMachine: CellMachine = null;
  orderMac: OrderMachine = null;
  propMac: PropMachine = null;
  itemSize: Size = new Size(112, 125);

  checkCount: number = 0;
  finishOrder: number = 0;
  readySettlement: boolean = false;
  reduceColorArr: SingleOrder[] = [];

  curLevelData: TB.LevelData;

  gameCoin: number;
  gameVisitorState: boolean[] = [];

  spineItem: Node;
  spineGrid: Node;
  // Show(): void {
  //   LayerManager.Singleton.showNode(this.loadRes);
  // }
  curGridCount: number;
  curLibIndex: number;
  reviveCount: number;
  adCount: number;

  useTimerCount: number;
  useTimer;

  initLevelData() {
    const gameLevel = DataMgr.gameParams.get(GameParams.gameLevel);
    // const gameLevel = 4;
    let levelId = Math.ceil(gameLevel / 5) * 100 + ((gameLevel - 1) % 5) + 1;
    const lastId = DataMgr.tables.TbLevel.getDataList()[DataMgr.tables.TbLevel.getDataList().length - 1].id;
    levelId = levelId >= lastId ? lastId : levelId;
    this.curLevelData = DataMgr.tables.TbLevel.get(levelId);
    this.finishOrder = 0;
    this.readySettlement = false;
    this.adCount = 0;
    this.gameCoin = 0;
    this.reviveCount = 1;
    this.curLibIndex = -1;
    // eslint-disable-next-line @typescript-eslint/no-unused-expressions
    this.useTimer != null && clearInterval(this.useTimer);
    this.useTimer = null;
    this.useTimerCount = 0;
    this.curGridCount = this.curLevelData.step;
    const libList = DataMgr.tables.TbColorLib.getDataList();
    if (this.curLevelData.colorLib != 0) this.curLibIndex = this.curLevelData.colorLib;
    else if (this.curLibIndex === -1) this.curLibIndex = 100 + MathUtil.randomIntegerBetween(0, libList.length) + 1;
    this.gameVisitorState = [true, false, false];
    this.startTimer();
  }

  startTimer() {
    // eslint-disable-next-line @typescript-eslint/no-unused-expressions
    this.useTimer != null && clearInterval(this.useTimer);
    this.useTimer = setInterval(() => {
      this.useTimerCount++;
    }, 1000);
  }

  // 结算游戏
  settlementGame(isPass: boolean = false) {
    if (this.useTimer === null) return;
    // eslint-disable-next-line @typescript-eslint/no-unused-expressions
    this.useTimer != null && clearInterval(this.useTimer);
    this.useTimer = null;
    // 结算
    SettlementModel.Ins().isPass = isPass;
    // GravityModel.I.track(GEEvent.STAGE_CHALLENGE, {
    //   stageID: `第${GameData.get(GameParams.gameLevel)}关`,
    //   result: isPass ? '成功' : '失败',
    //   reviveCount: 1 - this.reviveCount,
    //   stageDuration: this.useTimerCount,
    //   adCount: this.adCount,
    //   challengeCount: GameData.get(GameParams.gameChallenge)[`${GameData.get(GameParams.gameLevel)}`],
    // });

    AudioManager.Singleton.playSound(isPass ? SoundCode.WIN : SoundCode.LOSE);
    if (isPass) {
      DataMgr.changeGameAttr(GameParams.coin, 100);
      DataMgr.changeGameAttr(GameParams.gameLevel, 1);
      // RankModel.Ins().updateRank();
    }
    SettlementModel.Ins().Show();
  }

  /** 获取随机颜色数据 */
  getItemData(col: number = -1, row: number = -1) {
    const arr: GameColor[] = [];
    const idArr: string[] = [];
    DataMgr.tables.TbColorLib.get(this.curLibIndex).lib.forEach((id) => {
      idArr.push(id);
    });
    // console.log('beginArr', idArr.toString());
    const tempArr: string[] = [];
    const topItem = this.cellMachine.getGridItem(col, row - 1);
    const rightItem = this.cellMachine.getGridItem(col + 1, row);
    const downItem = this.cellMachine.getGridItem(col, row + 1);
    const leftItem = this.cellMachine.getGridItem(col - 1, row);

    const retColor: string[] = [];

    if (topItem != null) {
      if (retColor.indexOf(topItem.getColor(2)) === -1) retColor.push(topItem.getColor(2));
      if (retColor.indexOf(topItem.getColor(3)) === -1) retColor.push(topItem.getColor(3));
    }
    if (rightItem != null) {
      if (retColor.indexOf(rightItem.getColor(0)) === -1) retColor.push(rightItem.getColor(0));
      if (retColor.indexOf(rightItem.getColor(2)) === -1) retColor.push(rightItem.getColor(2));
    }
    if (downItem != null) {
      if (retColor.indexOf(downItem.getColor(0)) === -1) retColor.push(downItem.getColor(0));
      if (retColor.indexOf(downItem.getColor(1)) === -1) retColor.push(downItem.getColor(1));
    }
    if (leftItem != null) {
      if (retColor.indexOf(leftItem.getColor(1)) === -1) retColor.push(leftItem.getColor(1));
      if (retColor.indexOf(leftItem.getColor(3)) === -1) retColor.push(leftItem.getColor(3));
    }

    const filterArr = idArr.filter((id) => {
      return retColor.indexOf(id) === -1;
    });

    if (col != -1 && row != -1 && (Tool.judge(10) || filterArr.length <= 1)) {
      const id = filterArr[MathUtil.randomIntegerBetween(0, filterArr.length)];
      for (let i = 0; i < 4; i++) tempArr.push(id);
    } else {
      switch (filterArr.length) {
        case 1:
          for (let i = 0; i < 4; i++) tempArr.push(filterArr[0]);
          break;
        case 2:
        case 3:
          for (let i = 0; i < 4; i++) {
            const index = MathUtil.randomIntegerBetween(0, filterArr.length);
            let id = filterArr[index];
            let count = 0;
            tempArr.forEach((t) => {
              if (t === id) count++;
            });
            if (count >= 2) id = filterArr[(index + 1) % filterArr.length];
            tempArr.push(id);
          }
          break;
        default:
          for (let i = 0; i < 4; i++) {
            if (tempArr[i] != undefined) continue;
            const id = filterArr.splice(MathUtil.randomIntegerBetween(0, filterArr.length), 1).shift();
            tempArr[i] = id;
            if (Tool.judge(30)) {
              switch (i) {
                case 0:
                  tempArr[Tool.judge(50) ? 1 : 2] = id;
                  break;
                case 1:
                  tempArr[3] = id;
                  break;
                case 2:
                  tempArr[3] = id;
                  break;
              }
            }
          }
          break;
      }
    }

    console.log(col, row, tempArr.toString());

    // 将数据转换成GameColor
    let isSame = true;
    let lastId = ``;
    tempArr.forEach((id) => {
      if (lastId === ``) lastId = id;
      if (lastId != id) isSame = false;
    });

    if (isSame) {
      arr.push(new GameColor(`${tempArr[0]}`, ...[0, 1, 2, 3]));
    } else {
      tempArr.forEach((id, tempIndex) => {
        let ret = -1;
        arr.forEach((color, arrIndex) => {
          if (color.colorId == id) {
            if (color.posArr.length === 1) {
              switch (color.posArr[0]) {
                case 0:
                  if (tempIndex === 1 || tempIndex === 2) ret = arrIndex;
                  break;
                case 1:
                  if (tempIndex === 3) ret = arrIndex;
                  break;
                case 2:
                  if (tempIndex === 3) ret = arrIndex;
                  break;
              }
            }
          }
        });
        if (ret != -1) {
          arr[ret].posArr.push(tempIndex);
          arr[ret].posArr.sort((a, b) => a - b);
        } else arr.push(new GameColor(`${id}`, ...[tempIndex]));
      });
    }
    return arr;
  }

  /** 增加需求颜色 */
  addReduceData(color: string, count: number) {
    let index = -1;
    this.reduceColorArr.forEach((data, i) => {
      if (data.cake === color) {
        index = i;
      }
    });

    if (index != -1) {
      this.reduceColorArr[index].count += count;
    } else {
      this.reduceColorArr.push({ cake: color, count: count });
    }
  }

  /** 增加游戏金币 */
  addGameMoney(count: number, worldPos: Vec3 = null) {
    this.gameCoin += count;
    if (count > 0 && worldPos != null) {
      const coinParentUI = this.orderMac.coinParent.getComponent(UITransform);
      const beginPos = coinParentUI.convertToNodeSpaceAR(worldPos);
      let coinPos = this.orderMac.coinLab.node.getWorldPosition().clone();
      coinPos = coinParentUI.convertToNodeSpaceAR(coinPos);
      const func = () => {
        if (this.gameCoin <= 0) this.gameCoin = 0;
        this.orderMac.coinLab.string = `${this.gameCoin} G`;
        // this.orderMac.refreshVisitorOrder();
        if (this.orderMac.visitorItems.length > 1 && this.orderMac.visitorItems[1].btn_gold.active) this.orderMac.visitorItems[1].btn_gold.getComponent(Sprite).grayscale = this.gameCoin >= 100;
      };
      const length = Math.floor(count / 5) < 1 ? 1 : Math.floor(count / 5);
      for (let i = 0; i < length; i++) {
        const coin = this.orderMac.poolFac.pop('coin', 'maingame/effects', 'coin');
        const centerPos = beginPos.clone();
        centerPos.x += (Math.random() - 0.5) * 100;
        centerPos.y += (Math.random() - 0.5) * 20;
        this.orderMac.coinParent.addChild(coin);
        Tween.stopAllByTarget(coin);
        coin.setPosition(beginPos);
        coin.setScale(0, 0);
        tween(coin)
          .to(0.5, { position: centerPos, scale: v3(1, 1) }, { easing: 'backOut' })
          .delay(0.3)
          .to(0.2, { position: coinPos })
          .call(() => this.orderMac.poolFac.push(coin))
          .call(i == length - 1 ? func.bind(this) : null)
          .start();
      }
    } else {
      if (this.gameCoin <= 0) this.gameCoin = 0;
      this.orderMac.coinLab.string = `${this.gameCoin}`;
      if (this.orderMac.visitorItems[1].btn_gold.active) this.orderMac.visitorItems[1].btn_gold.getComponent(Sprite).grayscale = this.gameCoin >= 100;
      // this.orderMac.refreshVisitorOrder();
    }
  }

  /** 增加完成订单数 */
  addFinishOrder(visitorIndex: number) {
    console.log(`顾客${visitorIndex}完成订单`, this.finishOrder, this.orderMac.maxVisitorCount);

    if (this.readySettlement) return;
    AudioManager.Singleton.playSound(SoundCode.SELL);
    this.finishOrder++;
    console.log(`完成订单`, this.finishOrder);
    // 获取金币
    this.addGameMoney(25, this.orderMac.visitorItems[visitorIndex].node.getWorldPosition().clone());
    if (this.finishOrder >= this.orderMac.maxVisitorCount) {
      this.readySettlement = true;
      // if (this.cellMachine.releaseEnable) GameModel.Ins().settlementGame(true);
    }
  }
}
